package com.cgc.venus.server.utils;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.IOException;


/*
* httpclient 工具类
* */
public class HttpClientUtils {

    public static PoolingHttpClientConnectionManager cm = null;
    public static HttpClientUtils httpClientUtil = null;
    private final static int MAXTOTAL = 200;
    private final static int MAXPERROUTE = 20;
    private static final String APPLICATION_JSON = "application/json";
    private static final String CONTENT_TYPE_TEXT_JSON = "text/json";


    private HttpClientUtils(int maxTotal, int maxPerRoute) {
        cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(maxTotal);
        cm.setDefaultMaxPerRoute(maxPerRoute);
    }

    public HttpClientUtils getHttpClientInstance() {
        if (httpClientUtil == null) {
            httpClientUtil = new HttpClientUtils(MAXTOTAL, MAXPERROUTE);
        }
        return httpClientUtil;
    }

    public HttpClientUtils getHttpClientInstance(int maxTotal, int maxPerRoute) {
        if (httpClientUtil == null) {
            httpClientUtil = new HttpClientUtils(maxTotal, maxPerRoute);
        }
        return httpClientUtil;
    }

    /*
    * 带json参数的post请求非方法
    *
    * @param url 请求URL
    * @param paramJSON 请求json
    * @param timeOutParam 请求超时时间
    * */
    public static String doPostWithJSON(String url, String paramJSON, int timeOutParam) {
        String result = "";
        CloseableHttpClient httpclient = null;
        try {
            String encoderJson = paramJSON;
            httpclient = HttpClients.createDefault();
            // 构造一个post对象
            HttpPost httpPost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(timeOutParam) //请求获取数据的超时时间，单位毫秒。 如果访问一个接口，多少时间内无法返回数据，就直接放弃此次调用。
                    .setConnectTimeout(timeOutParam) // 设置连接超时时间，单位毫秒。
                    .setConnectionRequestTimeout(timeOutParam) //设置从connect Manager获取Connection 超时时间，单位毫秒。这个属性是新加的属性，因为目前版本是可以共享连接池的。
                    .build();//设置请求和传输超时时间
            // 设置超时
            httpPost.setConfig(requestConfig);
            httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);
            StringEntity se = new StringEntity(encoderJson);
            se.setContentType(CONTENT_TYPE_TEXT_JSON);
            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    APPLICATION_JSON));
            httpPost.setEntity(se);

            HttpResponse httpResponse = httpclient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = httpResponse.getEntity();
                result = EntityUtils.toString(httpEntity);// 取出应答字符串
                // 一般来说都要删除多余的字符
                result.replaceAll("\r", "");// 去掉返回结果中的"\r"字符，否则会在结果字符串后面显示一个小方格
            } else {
                httpPost.abort();
            }
        } catch (Exception e) {
            httpclient = null;
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
                httpclient = null;
            }
        }
        return result;
    }

    /*
    * post请求非方法
    *
    * @param url 请求URL
    * */
    public static String doPost(String url) {
        String result = "";
        CloseableHttpClient httpclient = null;
        try {
            // 将JSON进行UTF-8编码,以便传输中文
            httpclient = HttpClients.createDefault();
            // 构造一个post对象
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);
            HttpResponse httpResponse = httpclient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = httpResponse.getEntity();
                result = EntityUtils.toString(httpEntity);// 取出应答字符串
                // 一般来说都要删除多余的字符
                result.replaceAll("\r", "");// 去掉返回结果中的"\r"字符，否则会在结果字符串后面显示一个小方格
            } else {
                httpPost.abort();
            }
        } catch (Exception e) {
            httpclient = null;
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
                httpclient = null;
            }
        }
        return result;
    }

    /*
    * post请求非方法
    *
    * @param url 请求URL
    * @param timeOutParam 请求超时时间
    * */
    public static String doPost(String url, int timeOutParam) {
        String result = "";
        CloseableHttpClient httpclient = null;
        try {
            // 将JSON进行UTF-8编码,以便传输中文
            //String encoderJson = paramJSON;
            httpclient = HttpClients.createDefault();
            // 构造一个post对象
            HttpPost httpPost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(timeOutParam) //请求获取数据的超时时间，单位毫秒。 如果访问一个接口，多少时间内无法返回数据，就直接放弃此次调用。
                    .setConnectTimeout(timeOutParam) // 设置连接超时时间，单位毫秒。
                    .setConnectionRequestTimeout(timeOutParam) //设置从connect Manager获取Connection 超时时间，单位毫秒。这个属性是新加的属性，因为目前版本是可以共享连接池的。
                    .build();//设置请求和传输超时时间
            // 设置超时
            httpPost.setConfig(requestConfig);
            httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);
            HttpResponse httpResponse = httpclient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = httpResponse.getEntity();
                result = EntityUtils.toString(httpEntity);// 取出应答字符串
                // 一般来说都要删除多余的字符
                result.replaceAll("\r", "");// 去掉返回结果中的"\r"字符，否则会在结果字符串后面显示一个小方格
            } else {
                httpPost.abort();
            }
        } catch (Exception e) {
           httpclient = null;
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
                httpclient = null;
            }
        }
        return result;
    }


    /*
    * get 请求方法
    * @param url 请求的URL
    * */
    public static String doGet(String url,int timeOutParam) {
        String result = "";
        CloseableHttpClient httpclient = null;
        try {
            httpclient = HttpClients.createDefault();
            // 构造一个get对象
            HttpGet httpGet = new HttpGet(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(timeOutParam) //请求获取数据的超时时间，单位毫秒。 如果访问一个接口，多少时间内无法返回数据，就直接放弃此次调用。
                    .setConnectTimeout(timeOutParam) // 设置连接超时时间，单位毫秒。
                    .setConnectionRequestTimeout(timeOutParam) //设置从connect Manager获取Connection 超时时间，单位毫秒。这个属性是新加的属性，因为目前版本是可以共享连接池的。
                    .build();//设置请求和传输超时时间
            // 设置超时
            httpGet.setConfig(requestConfig);
            // 使用DefaultHttpClient类的execute方法发送HTTP GET请求，并返回HttpResponse对象。
            HttpResponse httpResponse = httpclient.execute(httpGet);// 其中HttpGet是HttpUriRequst的子类
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                HttpEntity httpEntity = httpResponse.getEntity();
                result = EntityUtils.toString(httpEntity);// 取出应答字符串
                // 一般来说都要删除多余的字符
                result.replaceAll("\r", "");// 去掉返回结果中的"\r"字符，否则会在结果字符串后面显示一个小方格
            } else {
                httpGet.abort();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            result = e.getMessage().toString();
        } catch (IOException e) {
            e.printStackTrace();
            result = e.getMessage().toString();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
                httpclient = null;
            }
        }
        return result;
    }

}
